﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Text;
using System.Web.UI.WebControls;
using H2.NET.Business.SMD.Service;
using H2.NET.Common;
using H2.NET.Web.Workflow.Helpers;
using H2.NET.Web.Workflow.Workflow;
using log4net;
using Ultimus.WFServer;
using H2.NET.Business.Core;
using H2.NET.Data.Common;

namespace H2.NET.Web.Workflow
{
    public partial class IncidentManage : DwzCode.BasePage
    {
        /// <summary>
        /// 日志记录
        /// </summary>
        private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        public string Status = "";
        public string From = "";
        public string To = "";
        public string Summary = "";
        public string ProcessName = "";

        private DataTable _dtIncidents = new DataTable();

        protected void Page_Load(object sender, EventArgs e)
        {
            var action = AksRequest.GetQueryStringValue("action");
            if (string.IsNullOrEmpty(action)) //默认页面加载
            {
                LoadIncidents();

                clsCmm.clsDB.Storage("bpmDB");
                var dtProcesses = clsCmm.clsDB.Query("SELECT DISTINCT PROCESSNAME FROM PROCESSES");
                rptProcesses.DataSource = dtProcesses;
                rptProcesses.DataBind();
            }
            else if (action == "cancel_incidents") //取消实例
            {
                CancelIncidents();
            }
            else if (action == "init_recipient") //初始化流程处理人
            {
                InitRecipient();
            }
        }

        private void InitRecipient()
        {
            
        }

        private void CancelIncidents()
        {
            var processNames = AksRequest.GetString("processNames");
            var aryProcessNames = string.IsNullOrEmpty(processNames) ? new string[0] : processNames.Split(',');
            var incidentNoes = AksRequest.GetString("incidentNoes");
            var aryIncidentNoes = string.IsNullOrEmpty(incidentNoes) ? new string[0] : incidentNoes.Split(',');
            var abortReason = AksRequest.GetString("abortreason");
            var process = string.Empty;
            var success = 0;
            var fail = 0;
            for (var i = 0; i < aryProcessNames.Length; i++)
            {
                //加载实例信息
                var incident = new Incident();
                var incidentNo = 0;
                int.TryParse(aryIncidentNoes[i], out incidentNo);
                var processName = string.IsNullOrEmpty(aryProcessNames[i]) ? "" : aryProcessNames[i].Trim();

                process += processName + "(" + incidentNo + ")" + ";";

                try
                {
                    var flag = incident.LoadIncident(processName, incidentNo);

                    if (!flag)
                    {
                        fail++;
                        continue;
                    }

                    Incident.Status status = null;
                    incident.GetIncidentStatus(out status);
                    if (status.nIncidentStatus == IncidentStatuses.INCIDENT_STATUS_ABORTED || status.nIncidentStatus == IncidentStatuses.INCIDENT_STATUS_COMPLETED)
                    {
                        fail++;
                        continue;
                    }

                    //执行任务取消
                    var strError = "";
                    flag = incident.AbortIncident(incident.strIncidentOwner, clsCmm.comm_userfullname + " " + System.DateTime.Now.ToString(), out strError);

                    if (flag && abortReason != "" && (incident.strProcessName.Contains("Store Deposit Change") || incident.strProcessName.Contains("Store Deposit Receive")
                        || incident.strProcessName.Contains("Store Data Change") || incident.strProcessName.Contains("New Store Application")))
                    {
                        BusinessService.SaveChildProcess(incident.strProcessName, incident.nIncidentNo, "abort",
                            System.DateTime.Now, clsCmm.comm_userfullname, abortReason);
                    }

                    if (flag)
                    {
                        success++;

                        var incidentManageLog = new t_log_IncidentManage
                        {
                            Process = processName,
                            Incident = incidentNo,
                            Status = true,
                            Action = "取消实例",
                            Description = "取消实例（" + incidentNo + "）成功",
                            Creator = UserAPI.UserFullName,
                            CreateOn = DateTime.Now
                        };
                        Storage.Save(incidentManageLog);
                    }
                    else
                    {
                        fail++;

                        var incidentManageLog = new t_log_IncidentManage
                        {
                            Process = processName,
                            Incident = incidentNo,
                            Status = false,
                            Action = "取消实例",
                            Description = "取消实例（" + incidentNo + "）失败",
                            Creator = UserAPI.UserFullName,
                            CreateOn = DateTime.Now
                        };
                        Storage.Save(incidentManageLog);
                    }
                }
                catch (Exception ex)
                {
                    // 记录错误日志
                    var errorLog = new t_log_IncidentManage
                    {
                        Process = process,
                        Status = false,
                        Action = "取消实例",
                        Description = "ERROR:" + ex.Message,
                        Creator = UserAPI.UserFullName,
                        Incident = incidentNo,
                        CreateOn = DateTime.Now
                    };
                    Storage.Save(errorLog);
                    Logger.Error(ex.Message);
                    fail++;
                }

            }

            WriteToClient("{\"success\":\"" + success + "\",\"fail\":\"" + fail + "\"}");

        }

        private string BuildSqlStr()
        {
            var strSql = new StringBuilder();
            strSql.Append("SELECT DISTINCT RTRIM(a.taskid) AS taskid");

            //中文的情况，流程名变化
            if (clsCmm.comm_language == "en-us" && Util.AppSettings("language").ToLower() == "yes")
            {
                strSql.Append(" ,h.processhelpurl as processname3");
                strSql.Append(" ,h.processname");
            }
            else
            {
                strSql.Append(" ,a.processname as processname3");
                strSql.Append(" ,a.processname");
            }

            strSql.Append(" ,a.incident ,a.steplabel ,a.taskuser ,a.assignedtouser , a.status, '' as status_name, '' as openform, RTRIM(a.helpurl) AS helpurl ");
            strSql.Append(",a.substatus ,a.starttime ,a.delaytime,a.overduetime ,a.urgentduetime ,i.summary,i.status AS i_status ,i.priority ,i.initiator,i.starttime AS i_starttime,i.endtime AS i_endtime ");
            strSql.Append(" FROM tasks a WITH (NOLOCK) LEFT JOIN initiate h WITH (NOLOCK) ON a.processname = h.processname LEFT JOIN PROCESSES p WITH (NOLOCK) ON h.PROCESSNAME = p.PROCESSNAME LEFT JOIN INCIDENTS i WITH (NOLOCK) ON h.PROCESSNAME = i.PROCESSNAME AND a.INCIDENT = i.INCIDENT LEFT JOIN TASKQUEUE tq WITH (NOLOCK) ON a.TASKID = tq.TASKID ");
            strSql.Append(" WHERE tq.TASKID IS NULL AND CHARINDEX('B', a.STEPID) > 0");

            var strProcessName = AksRequest.GetFormString("processName");
            if (!string.IsNullOrEmpty(strProcessName) && strProcessName.ToLower() != "all")
            {
                ProcessName = strProcessName.Trim();
                strSql.Append(" and a.processname='" + strProcessName + "'");
            }

            var nIncidentNoFrom = AksRequest.GetFormInt("incidentNoFrom");
            if (nIncidentNoFrom > 0)
            {
                From = nIncidentNoFrom.ToString();
                strSql.Append(" and a.incident >= " + nIncidentNoFrom + "");
            }

            var nIncidentNoTo = AksRequest.GetFormInt("incidentNoTo");
            if (nIncidentNoTo > 0)
            {
                To = nIncidentNoTo.ToString();
                strSql.Append(" and a.incident <= " + nIncidentNoTo + "");
            }

            var strSummary = AksRequest.GetFormString("summary");
            if (!string.IsNullOrEmpty(strSummary))
            {
                Summary = strSummary.Trim();
                strSql.Append(" and i.summary like '%" + strSummary + "%'");
            }

            var status = AksRequest.GetFormString("status");
            if (!string.IsNullOrEmpty(status))
            {
                Status = status.Trim();
                strSql.Append(" and i.status like '%" + status + "%'");
            }
            return strSql.ToString();
        }

        private string AppendForCount(string sqlStr)
        {
            return string.Format("select count(1) from ({0}) sub", sqlStr);
        }

        private string AppendForPaged(string sqlstr, int start, int end)
        {
            var orderby = "starttime desc";

            return string.Format(";with temp as(\r\n" +
                "	select row_number() over(order by sub.{3}) as rownum, sub.* from ({0}) sub\r\n)\r\n" +
                "select * from temp where rownum between {1} and {2}", sqlstr, start, end, orderby);
        }

        private DataTable PagedQuery()
        {
            clsCmm.clsDB.Storage("bpmDB");
            var sql = BuildSqlStr();
            TotalItemCount = Convert.ToInt32(clsCmm.clsDB.Query(AppendForCount(sql)).Rows[0][0]);
            PageNumber = Convert.ToInt32(Request.Form["pageNum"] ?? "1");

            Pager1.TotalItemCount = TotalItemCount;
            Pager1.PageSize = PageSize;
            Pager1.PageNumber = PageNumber;
            _dtIncidents = clsCmm.clsDB.Query(AppendForPaged(sql, PageSize * (PageNumber - 1) + 1, PageSize * PageNumber));

            for (var i = 0; i < _dtIncidents.Rows.Count; i++)
            {
                if (i >= _dtIncidents.Rows.Count) { break; }
                //处理表单类型 (自定义表单 & 标准表单)
                string HelpUrl = _dtIncidents.Rows[i]["helpurl"].ToString();
                if (!string.IsNullOrEmpty(HelpUrl) && HelpUrl.Length >= 5 && HelpUrl.Substring(0, 5).ToLower() == "form:")
                {
                    _dtIncidents.Rows[i]["openform"] = HelpUrl.Substring(5, HelpUrl.Length - 5);
                }
                else
                {
                    _dtIncidents.Rows[i]["openform"] = "workflow/openform.aspx";
                }

                #region SMD项目特殊处理

                var processName = _dtIncidents.Rows[i]["processname"].ToString().Trim();
                if (processName == "New Store Application" ||
                    processName == "Store Deposit Change" ||
                    processName == "Store Deposit Receive" ||
                    processName == "New Store Deposit Receive" ||
                    processName == "MDC Itss" ||
                    processName == "Store Data Change")
                {
                    _dtIncidents.Rows[i]["openform"] = "pages/smd/taskview.aspx";
                }

                #endregion
            }

            return _dtIncidents;
        }

        public void LoadIncidents()
        {
            try
            {
                if (Request.QueryString["read"] == "1")
                {
                    //加载列表
                    _dtIncidents = PagedQuery();
                    //数据合法性检查
                    if (_dtIncidents == null)
                    {
                        return;
                    }

                    //循环所有的记录集
                    for (var i = 0; i < _dtIncidents.Rows.Count; i++)
                    {
                        #region 流程状态转换

                        var nStatus = 0;
                        int.TryParse(_dtIncidents.Rows[i]["i_status"].ToString(), out nStatus);
                        var statusName = "";
                        switch (nStatus)
                        {
                            case IncidentStatuses.INCIDENT_STATUS_ACTIVE:
                                statusName = "Active";
                                break;
                            case IncidentStatuses.INCIDENT_STATUS_COMPLETED:
                                statusName = "Completed";
                                break;
                            case IncidentStatuses.INCIDENT_STATUS_ABORTED:
                                statusName = "Aborted";
                                break;
                            case IncidentStatuses.INCIDENT_STATUS_PENDING:
                                statusName = "Pending";
                                break;
                        }
                        _dtIncidents.Rows[i]["status_name"] = statusName;

                        #endregion
                    }

                    //第一次没有排序字段的情况
                    if (ViewState["OrderBy"] == null)
                    {
                        _dtIncidents.DefaultView.Sort = "starttime DESC";
                    }
                    else
                    {
                        _dtIncidents.DefaultView.Sort = ViewState["OrderBy"] + " " + ViewState["Order"];
                    }

                    gvInbox.DataSource = _dtIncidents;
                    gvInbox.DataBind();
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
        }
    }
}
